home *** CD-ROM | disk | FTP | other *** search
/ Tech Arsenal 1 / Tech Arsenal (Arsenal Computer).ISO / tek-19 / intrlib1.zip / TEXTWNDW.C < prev    next >
C/C++ Source or Header  |  1992-03-10  |  14KB  |  360 lines

  1. /******************************************************************************
  2. * Iteraction library - text windows.                          *
  3. *                                          *
  4. *                    Written by Gershon Elber,  Oct. 1990  *
  5. *******************************************************************************
  6. * Implements a text printf for graphics windows.                  *
  7. *******************************************************************************
  8. * History:                                      *
  9. *  29 Oct 90 - Version 1.0 by Gershon Elber.                      *
  10. ******************************************************************************/
  11.  
  12. #include <stdio.h>
  13. #include <string.h>
  14. #include <stdarg.h>
  15. #include <ctype.h>
  16. #ifdef __MSDOS__
  17. #include <mem.h>
  18. #endif /* __MSDOS__ */
  19. #include "intr_loc.h"
  20. #include "intr_gr.h"
  21.  
  22. static IntrBType SmoothScroll = FALSE;
  23. static IntrBType WasAPrintf = FALSE;
  24.  
  25. static void ScrollAndPrint(_IntrWindowStruct *Window);
  26.  
  27. /******************************************************************************
  28. * Select a window and initialize it to text drawing.                  *
  29. ******************************************************************************/
  30. void IntrTextInitWindow(int WindowID,
  31.             IntrBType ReadBottomLine,
  32.             IntrColorType TextColor,
  33.                         IntrColorType BottomLineColor,
  34.                         IntrScrlBarType HScrlBar,
  35.                         IntrScrlBarType VScrlBar,
  36.                         int NumOfLines,
  37.                         int LineLen)
  38. {
  39.     _IntrWindowStruct
  40.     *Window = _IntrFindWndwUsingID(WindowID);
  41.  
  42.     if (Window -> WindowType == INTR_WNDW_TEXT) {
  43.     _IntrFree(Window -> TextInfo -> TextData);             /* Delete old data. */
  44.     }
  45.     else
  46.         Window -> TextInfo = (_IntrWndwTextStruct *)
  47.                         _IntrMalloc(sizeof(_IntrWndwTextStruct));
  48.  
  49.     Window -> TextInfo -> TextData = (char *) _IntrMalloc(NumOfLines * ++LineLen);
  50.     Window -> TextInfo -> ReadBottomLine = ReadBottomLine;
  51.     Window -> TextInfo -> TextColor = TextColor;
  52.     Window -> TextInfo -> BottomLineColor = BottomLineColor;
  53.     Window -> TextInfo -> NumOfLines = NumOfLines;
  54.     Window -> TextInfo -> LineLen = LineLen;
  55.     Window -> TextInfo -> LinesInBuffer = 0;
  56.     Window -> TextInfo -> FirstDisplayed = 0;
  57.  
  58.     Window -> HScrlBar = HScrlBar;
  59.     Window -> VScrlBar = VScrlBar;
  60.     Window -> HScrlBarColor = Window -> VScrlBarColor = TextColor;
  61.     Window -> WindowType = INTR_WNDW_TEXT;
  62. }
  63.  
  64. /******************************************************************************
  65. * Free TextInfo structure.                              *
  66. ******************************************************************************/
  67. void _IntrTextWndwDelete(_IntrWndwTextStruct *TextInfo)
  68. {
  69.     _IntrFree(TextInfo -> TextData);
  70.     _IntrFree(TextInfo);
  71. }
  72.  
  73. /******************************************************************************
  74. * Set smooth scrolling for text windows.                      *
  75. ******************************************************************************/
  76. void IntrTextSetSmoothScroll(IntrBType SmoothScrolling)
  77. {
  78.     SmoothScroll = SmoothScrolling;
  79. }
  80.  
  81. /******************************************************************************
  82. * Draw all text defined for this window.                      *
  83. * It is assumed the window is all visible and cleared.                  *
  84. ******************************************************************************/
  85. void IntrTextWndwRefresh(int WindowID)
  86. {
  87.     IntrRType RelativePosition, DisplayedFraction;
  88.     _IntrWindowStruct
  89.     *Window = _IntrFindWndwUsingID(WindowID);
  90.     int i, j, NumOfDisplayedLines, FirstLine,
  91.     LineLen = Window -> TextInfo -> LineLen,
  92.         LinesInBuffer = Window -> TextInfo -> LinesInBuffer;
  93.     char
  94.         *TextData = Window -> TextInfo -> TextData;
  95.     IntrBType
  96.     LocalWasAPrintf = WasAPrintf;
  97.     _IntrWndwTextStruct
  98.         *TextInfo = Window -> TextInfo;
  99.  
  100.     WasAPrintf = FALSE;
  101.  
  102.     GRPushViewPort();
  103.     GRPushTextSetting();
  104.     GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP);
  105.     GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
  106.  
  107.     NumOfDisplayedLines = (Window -> BBox.Ymax - Window -> BBox.Ymin -
  108.                          (TEXT_BORDER << 1)) / TEXT_BASE_LINE - 2;
  109.     if (TextInfo -> ReadBottomLine) NumOfDisplayedLines--;
  110.     if (NumOfDisplayedLines < 0) NumOfDisplayedLines = 0;
  111.     
  112.     _GRSetViewPort(Window -> BBox.Xmin + TEXT_BORDER,
  113.                Window -> BBox.Ymin + TEXT_BORDER,
  114.                    Window -> BBox.Xmax - TEXT_BORDER,
  115.                    Window -> BBox.Ymax - TEXT_BORDER);
  116.  
  117.     IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH);
  118.     if (LinesInBuffer > NumOfDisplayedLines) {
  119.         DisplayedFraction = ((IntrRType) NumOfDisplayedLines) / LinesInBuffer;
  120.     if (LocalWasAPrintf) {
  121.             RelativePosition = 1.0 - DisplayedFraction;
  122.         for (i = 0; i <= NumOfDisplayedLines; i++)
  123.                 GRSText(0, i * TEXT_BASE_LINE,
  124.                 &TextData[LineLen * (NumOfDisplayedLines - i)]);
  125.             TextInfo -> FirstDisplayed = 0;         /* Allow smooth scroll. */
  126.         }
  127.         else {
  128.             if (Window -> VScrlBar != INTR_SCRLBAR_NONE &&
  129.         _IntrAsyncLastEvent.AsyncEvent == ASYNC_EVNT_VSCRLBAR) {
  130.             RelativePosition = _IntrAsyncLastEvent.R;
  131.                 if (RelativePosition > 1.0 - DisplayedFraction)
  132.                     RelativePosition = 1.0 - DisplayedFraction;
  133.             }
  134.             else {
  135.                 RelativePosition = 1.0 - DisplayedFraction;
  136.             }
  137.             j = ((int) ((1.0 - DisplayedFraction - RelativePosition) *
  138.                                           LinesInBuffer));
  139.         for (i = 0; i <= NumOfDisplayedLines; i++) {
  140.         if (NumOfDisplayedLines - i + j < TextInfo -> LinesInBuffer)
  141.                     GRSText(0, i * TEXT_BASE_LINE,
  142.                  &TextData[LineLen * (NumOfDisplayedLines - i + j)]);
  143.             }
  144.             TextInfo -> FirstDisplayed = j;
  145.         }
  146.     }
  147.     else {
  148.         RelativePosition = 0.0;
  149.     DisplayedFraction = 1.0;
  150.         FirstLine = NumOfDisplayedLines - LinesInBuffer;
  151.         for (i = 1; i <= LinesInBuffer; i++)
  152.             GRSText(0, (FirstLine + i) * TEXT_BASE_LINE,
  153.                     &TextData[LineLen * (LinesInBuffer - i)]);
  154.     TextInfo -> FirstDisplayed = 0;             /* Allow smooth scroll. */
  155.     }
  156.  
  157.     switch (Window -> VScrlBar) {
  158.     case INTR_SCRLBAR_LEFT:
  159.             IntrWndwUpdateScrollBar(WindowID, TRUE,
  160.                             RelativePosition, DisplayedFraction);
  161.             break;
  162.     case INTR_SCRLBAR_RIGHT:
  163.             IntrWndwUpdateScrollBar(WindowID, TRUE,
  164.                             RelativePosition, DisplayedFraction);
  165.             break;
  166.     }
  167.  
  168.     IntrPushKbdEvent(KEY_REFRESH);
  169.  
  170.     GRPopTextSetting();
  171.     GRPopViewPort();
  172. }
  173.  
  174. /******************************************************************************
  175. * Scroll one line and print the new line on the bottom.                  *
  176. ******************************************************************************/
  177. static void ScrollAndPrint(_IntrWindowStruct *Window)
  178. {
  179.     int i, Xmax, Ymax;
  180.     IntrRType RelativePosition, DisplayedFraction;
  181.     VoidPtr LineBuffer;
  182.     _IntrWndwTextStruct
  183.         *TextInfo = Window -> TextInfo;
  184.  
  185.     TextInfo -> NumOfDisplayedLines = (Window -> BBox.Ymax -
  186.                Window -> BBox.Ymin - (TEXT_BORDER << 1)) / TEXT_BASE_LINE - 2;
  187.     if (TextInfo -> ReadBottomLine)
  188.         TextInfo -> NumOfDisplayedLines--;
  189.     if (TextInfo -> NumOfDisplayedLines < 0)
  190.     TextInfo -> NumOfDisplayedLines = 0;
  191.     
  192.     if (IntrWndwIsAllVisible(Window -> WindowID)) {
  193.         GRPushViewPort();
  194.         _GRSetViewPort(0, 0, GRScreenMaxX, GRScreenMaxY);
  195.     GRPushTextSetting();
  196.     GRSetTextJustify(GR_TEXT_HJUSTIFY_LEFT, GR_TEXT_VJUSTIFY_TOP);
  197.     GRSetSTextStyle(GR_FONT_DEFAULT, GR_HORIZ_DIR, GR_TEXT_MAG_1);
  198.  
  199.     if (SmoothScroll && TextInfo -> FirstDisplayed == 0) {
  200.         IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH);
  201.  
  202. #ifdef __MSDOS__
  203.             LineBuffer = _IntrMalloc(GRGetImageBufferSize(Window -> BBox.Xmin, 0,
  204.                                           Window -> BBox.Xmax, 0));
  205. #endif /* __MSDOS__ */
  206.         _GRSetViewPort(Window -> BBox.Xmin + TEXT_BORDER,
  207.                        Window -> BBox.Ymin + TEXT_BORDER,
  208.                            Window -> BBox.Xmax - TEXT_BORDER,
  209.                            Window -> BBox.Ymax - TEXT_BORDER);
  210.  
  211.             /* Scroll full base line. */
  212.             Xmax = Window -> BBox.Xmax - Window -> BBox.Xmin - (TEXT_BORDER << 1);
  213.             Ymax = Window -> BBox.Ymax - Window -> BBox.Ymin - (TEXT_BORDER << 1);
  214.         for (i = TEXT_BASE_LINE; i <= Ymax; i++) {
  215. #ifdef __MSDOS__
  216.             GRGetImageBuffer(0, i, Xmax, i, LineBuffer);
  217.             GRPutImageBuffer(0, i - TEXT_BASE_LINE, LineBuffer);
  218. #endif /* __MSDOS__ */
  219. #ifdef DJGCC
  220.         GRPutImageBuffer(0, i - TEXT_BASE_LINE,
  221.                  GRGetImageBuffer(0, i, Xmax, i));
  222. #endif /* DJGCC */
  223.             }
  224.  
  225. #ifdef __MSDOS__
  226.             _IntrFree(LineBuffer);
  227. #endif /* __MSDOS__ */
  228.  
  229.             /* Clear old bottom string and print new one. */
  230.         IntrAllocColor(Window -> BackColor, INTR_INTENSITY_HIGH);
  231.             GRSBar(0, TextInfo -> NumOfDisplayedLines * TEXT_BASE_LINE,
  232.                    Xmax, TextInfo -> NumOfDisplayedLines * TEXT_BASE_LINE + 8);
  233.         IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH);
  234.             GRSText(0, TextInfo -> NumOfDisplayedLines * TEXT_BASE_LINE,
  235.                     &TextInfo -> TextData[0]);
  236.  
  237.         if (TextInfo -> LinesInBuffer > TextInfo -> NumOfDisplayedLines) {
  238.                 RelativePosition =
  239.                     1.0 - ((IntrRType) TextInfo -> NumOfDisplayedLines) /
  240.                                     TextInfo -> LinesInBuffer;
  241.                 DisplayedFraction = 1.0 - RelativePosition;
  242.             }
  243.             else {
  244.             RelativePosition = 0.0;
  245.         DisplayedFraction = 1.0;
  246.             }
  247.  
  248.         switch (Window -> VScrlBar) {
  249.         case INTR_SCRLBAR_LEFT:
  250.                 IntrWndwUpdateScrollBar(Window -> WindowID, TRUE,
  251.                                   RelativePosition, DisplayedFraction);
  252.                 break;
  253.         case INTR_SCRLBAR_RIGHT:
  254.                 IntrWndwUpdateScrollBar(Window -> WindowID, TRUE,
  255.                                   RelativePosition, DisplayedFraction);
  256.                 break;
  257.         }
  258.         }
  259.         else {                             /* No smooth scrolling. */
  260.         TextInfo -> FirstDisplayed = 0;
  261.  
  262.         IntrAllocColor(Window -> BackColor, INTR_INTENSITY_HIGH);
  263.         GRSBar(Window -> BBox.Xmin, Window -> BBox.Ymin,
  264.                Window -> BBox.Xmax, Window -> BBox.Ymax);
  265.             WasAPrintf = TRUE;
  266.         IntrTextWndwRefresh(Window -> WindowID);
  267.         }
  268.  
  269.     GRPopViewPort();
  270.     GRPopTextSetting();
  271.     }
  272.     else {
  273.     /* Need to pop up the window which probably will refresh all text. */
  274.         IntrWndwPop(Window -> WindowID, TRUE, FALSE);
  275.     }
  276. }
  277.  
  278. /******************************************************************************
  279. * Printf to the specified window.                          *
  280. ******************************************************************************/
  281. void IntrPrintf(int WindowID, IntrBType UpdateWindow, char *CtrlStr, ...)
  282. {
  283.     va_list ArgPtr;
  284.     _IntrWindowStruct
  285.     *Window = _IntrFindWndwUsingID(WindowID);
  286.     _IntrWndwTextStruct
  287.         *TextInfo = Window -> TextInfo;
  288.     int i,j,
  289.         BufferSize = (Window -> TextInfo -> NumOfLines - 1) *
  290.                              (Window -> TextInfo -> LineLen);
  291.     char Line[256], *p,
  292.     *TempBuffer = _IntrMalloc(BufferSize);
  293.  
  294.     if (Window -> WindowType != INTR_WNDW_TEXT)
  295.     IntrFatalError("Window is not initialized to support text.");
  296.  
  297.     /* Move all lines one place up. Since both source and destination share  */
  298.     /* the same space we do it in two spaces.                     */
  299.     GEN_COPY(TempBuffer,
  300.          &Window -> TextInfo -> TextData[0],
  301.          BufferSize);
  302.     GEN_COPY(&Window -> TextInfo -> TextData[Window -> TextInfo -> LineLen],
  303.          TempBuffer,
  304.          BufferSize);
  305.     _IntrFree(TempBuffer);
  306.  
  307.     va_start(ArgPtr, CtrlStr);
  308.     vsprintf(Line, CtrlStr, ArgPtr);
  309.     va_end(ArgPtr);
  310.  
  311.     p = TextInfo -> TextData;
  312.     for (i = j = 0; i < TextInfo -> LineLen - 1 && Line[j]; j++) {
  313.     if (iscntrl(Line[j])) {
  314.         if (Line[j] == 9) {                     /* It is a tab. */
  315.         do p[i++] = ' ';
  316.                 while (i < TextInfo -> LineLen && (i & 0x07) != 0);
  317.             }
  318.         }
  319.         else
  320.             p[i++] = Line[j];
  321.     }
  322.     p[i] = 0;
  323.  
  324.     if (++TextInfo -> LinesInBuffer > TextInfo -> NumOfLines)
  325.     TextInfo -> LinesInBuffer = TextInfo -> NumOfLines;
  326.  
  327.     if (UpdateWindow)
  328.         ScrollAndPrint(Window);
  329.     else
  330.         TextInfo -> FirstDisplayed = -1;     /* Enforce full window refresh. */
  331. }
  332.  
  333. /******************************************************************************
  334. * Read a line input at a bottom of a given window into buffer.              *
  335. ******************************************************************************/
  336. void IntrGetLineWindow(int WindowID, char *Buffer, int BufferLen)
  337. {
  338.     int GRLastColor = GRGetColor();
  339.     _IntrWindowStruct
  340.     *Window = _IntrFindWndwUsingID(WindowID);
  341.     _IntrWndwTextStruct
  342.         *TextInfo = Window -> TextInfo;
  343.     int WindowLen = (Window -> BBox.Xmax - Window -> BBox.Xmin -
  344.                     (TEXT_BORDER << 1)) / GRGetTextWidth("M");
  345.  
  346.     GRPushViewPort();
  347.     _GRSetViewPort(Window -> BBox.Xmin, Window -> BBox.Ymin,
  348.            Window -> BBox.Xmax, Window -> BBox.Ymax);
  349.  
  350.     GRGetGraphicLine(WindowID, TEXT_BORDER << 1,
  351.                   Window -> BBox.Ymax - Window -> BBox.Ymin -
  352.                        TEXT_BORDER - GRGetTextHeight("M"),
  353.                      Buffer, BufferLen, WindowLen,
  354.                      IntrAllocColor(TextInfo -> TextColor, INTR_INTENSITY_VHIGH),
  355.                      IntrAllocColor(Window -> BackColor, INTR_INTENSITY_HIGH));
  356.  
  357.     GRSetColor(GRLastColor);
  358.     GRPopViewPort();
  359. }
  360.